package com.miplus.ccrm.core.service.cust;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.*;
import com.miplus.ccrm.core.controller.vo.cust.*;
import com.miplus.ccrm.core.mapper.SysTagsMapper;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.mapper.ConCustomerMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
* @author pc
* @description 针对表【con_customer(客户表)】的数据库操作Service实现
* @createDate 2024-03-14 11:23:47
*/
@Service
public class ConCustomerServiceImpl extends MPJBaseServiceImpl<ConCustomerMapper, ConCustomer>
    implements ConCustomerService{

    @Resource
    private ConCustomertagService conCustomertagService;

    @Resource
    private SysTagsMapper sysTagsMapper;

    private MPJLambdaWrapper getQueryWrapper(JSysUser user,CustReqVo paras)
    {
        String $usrid=user.getUsrid();
        String tags=JPubUtils.getInString(paras.getTags());
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        String phnstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_PHN);
        boolean enviewall=JUsrPerm.viewAllFiCase(user);
        //.apply(!enviewall,"fc_hasCustPurview({0},t.customernumber)>0",$usrid)
        MPJLambdaWrapper quyWrapper=
                new MPJLambdaWrapper<ConCustomer>()
                        .selectAs("fun_getnames('CUST.TYPE',t.type)",CustResVo::getTypedsc)
                        .selectAs("fun_getnames('DATA.ORIGIN',t.origin)",CustResVo::getOrigindsc)
                        .selectAs("fun_getnames('CON.SEX',t.gender)", CustResVo::getGenderdsc)
                        .selectAs("fun_getnames('MARRIAGE.STATUS',t.marrgstatus)",CustResVo::getMarrgstatus)
                        .selectAs("fun_getnames('CON.EDU',t.heightedudegr)", CustResVo::getHeightedudegr)
                        .selectAs("fun_getnames('CON.PSTN',t.pstn)",CustResVo::getPstn)
                        .selectAs("fun_getnames('CON.CERTTYPE',t.openacctcerttype)",CustResVo::getOpenacctcerttype)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.openacctcertno,'%s')",$usrid,JUsrPerm.DISSTAR_IDNO,idstar),CustResVo::getOpenacctcertno)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.custphone,'%s')",$usrid,JUsrPerm.DISSTAR_PHN,phnstar),CustResVo::getCustphone)
                        .select(ConCustomer::getCustomernumber,ConCustomer::getType,ConCustomer::getOrigin,ConCustomer::getGender,
                                ConCustomer::getCreatedby,ConCustomer::getCreateddate,ConCustomer::getProvince,ConCustomer::getCity,
                                ConCustomer::getRemark,ConCustomer::getCustname,ConCustomer::getCustenname,ConCustomer::getBirthday,
                                ConCustomer::getCorpname,ConCustomer::getCustemail,ConCustomer::getRisklevel,ConCustomer::getCustacctorgno,
                                ConCustomer::getLastmodifieddate,ConCustomer::getLastmodifiedby,ConCustomer::getFlevel)
                        .eq(JPubUtils.IsNotEmpty(paras.getCustomernumber()),"customernumber",paras.getCustomernumber())
                        .eq(JPubUtils.IsNotEmpty(paras.getIdnumber()),"openacctcertno",paras.getIdnumber())
                        .exists(!enviewall,String.format("select 1 from fi_creditcases fi where fi.customernumber=t.customernumber and (fi.sendtousr='%s' or fi.sendtodept in(select grm.grpid from sys_grpmgr grm where grm.grpmanagerid='%s'))",$usrid,$usrid))
                        .eq(JPubUtils.IsNotEmpty(paras.getGender()),"gender",paras.getGender())
                        .eq(JPubUtils.IsNotEmpty(paras.getProvince()),"province",paras.getProvince())
                        .eq(JPubUtils.IsNotEmpty(paras.getCity()),"city",paras.getCity())
                        .eq(JPubUtils.IsNotEmpty(paras.getType()),"type",paras.getType())
                        .eq(JPubUtils.IsNotEmpty(paras.getRisklevel()),"risklevel",paras.getRisklevel())
                        .eq(JPubUtils.IsNotEmpty(paras.getOrigin()),ConCustomer::getOrigin,paras.getOrigin())
                        .likeRight(JPubUtils.IsNotEmpty(paras.getCustname()),"custname",paras.getCustname())
                        .between(JPubUtils.IsNotEmpty(paras.getStartdt()), ConCustomer::getCreateddate,JPubUtils.StringToDate(paras.getStartdt()),JPubUtils.StringToDate(paras.getEnddt()))
                        .in(JPubUtils.IsNotEmpty(paras.getIdnumberlist()),ConCustomer::getOpenacctcertno,paras.getIdnumberlist())
                        .in(JPubUtils.IsNotEmpty(paras.getCustidlist()),ConCustomer::getCustomernumber,paras.getCustidlist())
                        .exists(JPubUtils.IsNotEmpty(tags),String.format("select 1 from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s')",tags))
                        .exists(JPubUtils.IsNotEmpty(paras.getPhone()), String.format("select 1 from con_contact ct where ct.customernumber=t.customernumber and ct.phone='%s'",paras.getPhone()))
                        .exists(JPubUtils.IsNotEmpty(paras.getFicaseid()), String.format("select 1 from fi_creditcases fi where fi.customernumber=t.customernumber and fi.creditcaseid=%d",paras.getFicaseid()))
                        .exists(JPubUtils.IsNotEmpty(paras.getProdtype()), String.format("select 1 from fi_creditcases fi where fi.customernumber=t.customernumber and fi.prodtype='%s'",paras.getProdtype()));

        if(JPubUtils.IsEqual(paras.getSystype(),"1")){
            quyWrapper.exists(JPubUtils.IsNotEmpty(paras.getBillno()),String.format("select 1 from iou_bill bi where bi.customernumber=t.customernumber and bi.billid='%s'",paras.getBillno()));
        }
        else{
            quyWrapper.exists(JPubUtils.IsNotEmpty(paras.getCardno()), String.format("select 1 from credit_card crd where crd.cust_no=t.customernumber and crd.card_no='%s'", paras.getCardno()));
        }

        return quyWrapper;
    }

    @Override
    public IPage<CustResVo> customerQuery(JSysUser user, CustReqVo paras)
    {
        MPJLambdaWrapper quyWrapper=getQueryWrapper(user,paras);
        return selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                CustResVo.class,
                quyWrapper
        );
    }

    @Override
    public CustResVo customerInfo(JSysUser user,String custid)
    {
        String $usrid=user.getUsrid();
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        String phnstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_PHN);
        boolean enviewall=JUsrPerm.viewAllFiCase(user);

        CustResVo resVo=selectJoinOne(CustResVo.class,
                new MPJLambdaWrapper<ConCustomer>()
                        .selectAs("fun_getnames('CUST.TYPE',t.type)",CustResVo::getTypedsc)
                        .selectAs("fun_getnames('DATA.ORIGIN',t.origin)",CustResVo::getOrigindsc)
                        .selectAs("fun_getnames('CON.SEX',t.gender)", CustResVo::getGenderdsc)
                        .selectAs("fun_getnames('MARRIAGE.STATUS',t.marrgstatus)",CustResVo::getMarrgstatus)
                        .selectAs("fun_getnames('CON.EDU',t.heightedudegr)", CustResVo::getHeightedudegr)
                        .selectAs("fun_getnames('CON.PSTN',t.pstn)",CustResVo::getPstn)
                        .selectAs("fun_getnames('CON.CERTTYPE',t.openacctcerttype)",CustResVo::getOpenacctcerttype)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.openacctcertno,'%s')",$usrid,JUsrPerm.DISSTAR_IDNO,idstar),CustResVo::getOpenacctcertno)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.custphone,'%s')",$usrid,JUsrPerm.DISSTAR_PHN,phnstar),CustResVo::getCustphone)
                        .select(ConCustomer::getCustomernumber,ConCustomer::getType,ConCustomer::getOrigin,ConCustomer::getGender,ConCustomer::getAge,
                                ConCustomer::getCreatedby,ConCustomer::getCreateddate,ConCustomer::getProvince,ConCustomer::getCity,
                                ConCustomer::getRemark,ConCustomer::getCustname,ConCustomer::getCustenname,ConCustomer::getBirthday,
                                ConCustomer::getCorpname,ConCustomer::getCustemail,ConCustomer::getRisklevel,ConCustomer::getFlevel,
                                ConCustomer::getLastmodifieddate)
                        //.apply(!enviewall,"fc_hasCustPurview({0},t.customernumber)>0",$usrid)
                        .eq("customernumber",custid)
                );
        List<ConCustomertag> custtags=conCustomertagService.list(
                new QueryWrapper<ConCustomertag>().eq("custid",custid)
        );
        if(custtags!=null&&custtags.size()>0){
            List<String> tags=new LinkedList<>();
            for (ConCustomertag t : custtags){
                tags.add(t.getId());
            }
            resVo.setTags(tags);
        }

        return resVo;
    }

    @Override
    public CustResVo customerInfoByPhone(JSysUser user, String custphone) {
        String $usrid=user.getUsrid();
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        String phnstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_PHN);
        boolean enviewall=JUsrPerm.viewAllFiCase(user);

        CustResVo resVo=selectJoinOne(CustResVo.class,
                new MPJLambdaWrapper<ConCustomer>()
                        .selectAs("fun_getnames('CUST.TYPE',t.type)",CustResVo::getTypedsc)
                        .selectAs("fun_getnames('DATA.ORIGIN',t.origin)",CustResVo::getOrigindsc)
                        .selectAs("fun_getnames('CON.SEX',t.gender)", CustResVo::getGenderdsc)
                        .selectAs("fun_getnames('MARRIAGE.STATUS',t.marrgstatus)",CustResVo::getMarrgstatus)
                        .selectAs("fun_getnames('CON.EDU',t.heightedudegr)", CustResVo::getHeightedudegr)
                        .selectAs("fun_getnames('CON.PSTN',t.pstn)",CustResVo::getPstn)
                        .selectAs("fun_getnames('CON.CERTTYPE',t.openacctcerttype)",CustResVo::getOpenacctcerttype)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.openacctcertno,'%s')",$usrid,JUsrPerm.DISSTAR_IDNO,idstar),CustResVo::getOpenacctcertno)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.custphone,'%s')",$usrid,JUsrPerm.DISSTAR_PHN,phnstar),CustResVo::getCustphone)
                        .select(ConCustomer::getCustomernumber,ConCustomer::getType,ConCustomer::getOrigin,ConCustomer::getGender,ConCustomer::getAge,
                                ConCustomer::getCreatedby,ConCustomer::getCreateddate,ConCustomer::getProvince,ConCustomer::getCity,
                                ConCustomer::getRemark,ConCustomer::getCustname,ConCustomer::getCustenname,ConCustomer::getBirthday,
                                ConCustomer::getCorpname,ConCustomer::getCustemail,ConCustomer::getRisklevel,ConCustomer::getFlevel,
                                ConCustomer::getLastmodifieddate)
                        //.apply(!enviewall,"fc_hasCustPurview({0},t.customernumber)>0",$usrid)
                        .eq("custphone",custphone)
        );
        if (JPubUtils.IsNotEmpty(resVo)) {
            List<ConCustomertag> custtags = conCustomertagService.list(
                    new QueryWrapper<ConCustomertag>().eq("custid", resVo.getCustomernumber())
            );
            if (custtags != null && custtags.size() > 0) {
                List<String> tags = new LinkedList<>();
                for (ConCustomertag t : custtags) {
                    tags.add(t.getId());
                }
                resVo.setTags(tags);
            }
        }
        return resVo;
    }

    @Override
    public CmdResVo updateTags(CustTagReqVo paras)
    {
        conCustomertagService.remove(
                new QueryWrapper<ConCustomertag>()
                        .eq("custid",paras.getCustid())
                        .notIn("tid","SYS")
        );
        int ret=0;
        //不要判定上面remove成功与否，失败就异常了，如果没有值，remove会返回false
        if(paras.getTags()!=null){
            List<ConCustomertag> ll=new ArrayList<>();
            for (String id : paras.getTags()){
                SysTags sysTags=sysTagsMapper.tagsSelect(id);
                if(!JPubUtils.IsEqual(sysTags.getTid(),"SYS")) {
                    ConCustomertag tag = new ConCustomertag();
                    tag.setCustid(paras.getCustid());
                    tag.setId(id);
                    tag.setTid(sysTags.getTid());
                    ll.add(tag);
                    ret++;
                }
            }
            if(ret>0) {
                conCustomertagService.saveBatch(ll);
            }
        }

        return new CmdResVo(ret,paras.getCustid());
    }

    @Override
    public int addTag(String custid,String tid,String tagid)
    {
        return addTag(custid,tid,tagid,null);
    }

    @Override
    public int addTag(String custid,String tid,String tagid,String batchid)
    {
        conCustomertagService.remove(
                new QueryWrapper<ConCustomertag>()
                        .eq("custid",custid)
                        .eq("id",tagid)
        );
        //不要判定上面remove成功与否，失败就异常了，如果没有值，remove会返回false
        ConCustomertag tag=new ConCustomertag();
        tag.setCustid(custid);
        tag.setTid(tid);
        tag.setId(tagid);
        tag.setBatchid(batchid);

        int ret=conCustomertagService.getBaseMapper().insert(tag);
        return ret;
    }

    @Override
    public int delTag(String batchid)
    {
        int ret=conCustomertagService.getBaseMapper().delete(
                new QueryWrapper<ConCustomertag>()
                        .eq("batchid",batchid)
        );
        return ret;
    }

    @Override
    public int delTag(String custid,String tagid)
    {
        int ret=conCustomertagService.getBaseMapper().delete(
                new QueryWrapper<ConCustomertag>()
                        .eq("custid",custid)
                        .eq("id",tagid)
        );
        return ret;
    }

    @Override
    public String getCustNumber(String idnumber)
    {
        ConCustomer customer=selectJoinOne(ConCustomer.class,
                new MPJLambdaWrapper<ConCustomer>()
                        .eq(ConCustomer::getOpenacctcertno,idnumber)
        );
        if(customer==null) return "";
        return customer.getCustomernumber();
    }

    @Override
    public String getCustId(String custid)
    {
        ConCustomer customer=selectJoinOne(ConCustomer.class,
                new MPJLambdaWrapper<ConCustomer>()
                        .eq(ConCustomer::getCustomernumber,custid)
        );
        if(customer==null) return "";
        return customer.getCustomernumber();
    }

    @Override
    public int hasCustomer(String custnumber)
    {
        ConCustomer customer=selectJoinOne(ConCustomer.class,
                new MPJLambdaWrapper<ConCustomer>()
                        .eq(ConCustomer::getCustomernumber,custnumber)
        );
        if(customer==null) return 0;
        return 1;
    }

    @Override
    public CmdResVo custInsert(String $usrid, CustAddVo paras) {
        ConCustomer def=new ConCustomer();
        BeanUtils.copyProperties(paras,def);
        def.setType(1);
        def.setOrigin("02");
        def.setCreatedby($usrid);
        def.setCreateddate(new Date());
        def.setLastmodifiedby($usrid);
        def.setLastmodifieddate(new Date());
        int ret=baseMapper.insert(def);
        return new CmdResVo(ret,def.getCustomernumber());
    }

    @Override
    public CmdResVo custUpdate(String $usrid, CustEditVo paras) {
        String custid=paras.getCustomernumber();
        if(JPubUtils.IsEmpty(custid)){
            throw new ServiceException(EnumRCode.ArgErr.value,EnumRCode.ArgErr.name);
        }else{
            if(hasCustomer(custid)==0){
                throw new ServiceException(EnumRCode.NoFindCust.value,EnumRCode.NoFindCust.name);
            }
        }

        ConCustomer def=new ConCustomer();
        BeanUtils.copyProperties(paras,def);
        def.setType(1);
        def.setOrigin("02");
        def.setLastmodifiedby($usrid);
        def.setLastmodifieddate(new Date());
        int ret=baseMapper.updateById(def);
        return new CmdResVo(ret,def.getCustomernumber());
    }
}




